<!-- 备件管理-备件出库页面 -->
<template>
  <div>
    <div v-show="isMain" class="equip-wrap-common">
      <px-form class="custom-form-ui equip-form" :model="queryParams" label-position="right" label-width="120px">
        <px-row :gutter="16">
          <px-col :span="6">
            <px-form-item label="出库单号">
              <px-input
                v-model="queryParams.outNum"
                placeholder="请输入出库单号"
                autocomplete="off"
                maxlength="50"
                clearable
                @blur="queryParams.outNum = $event.target.value.trim()"
                @keyup.enter="queryTable"
              >
                <template #suffix>
                  <px-icon style="cursor: pointer" @click="queryTable">
                    <search />
                  </px-icon>
                </template>
              </px-input>
            </px-form-item>
          </px-col>
          <px-col :span="6">
            <px-form-item label="名称">
              <px-input
                v-model="queryParams.spareName"
                placeholder="请输入名称"
                autocomplete="off"
                maxlength="50"
                clearable
                @blur="queryParams.spareName = $event.target.value.trim()"
                @keyup.enter="queryTable"
              >
                <template #suffix>
                  <px-icon style="cursor: pointer" @click="queryTable">
                    <search />
                  </px-icon>
                </template>
              </px-input>
            </px-form-item>
          </px-col>
          <px-col :span="6">
            <EquipClassSelect :className="queryParams.className" @changeClassName="changeClassName" />
          </px-col>
          <px-col :span="6"
            ><px-form-item label="种类">
              <px-select v-model="queryParams.category" filterable clearable placeholder="请选择种类">
                <px-option v-for="item in categoryList" :key="item.value" :label="item.name" :value="item.value" />
              </px-select>
            </px-form-item>
          </px-col>
          <px-col :span="6">
            <px-form-item label="用途" prop="used">
              <px-select v-model="queryParams.used" placeholder="请选择用途" filterable clearable>
                <px-option v-for="item in usedList" :key="item.id" :label="item.name" :value="item.value" />
              </px-select>
            </px-form-item>
          </px-col>
          <px-col :span="6">
            <px-form-item label="领用人" prop="recipientId">
              <px-select-v2 v-model="queryParams.recipientId" filterable clearable :options="recipientIdList" placeholder="请选择领用人" />
            </px-form-item>
          </px-col>

          <px-col :span="6">
            <px-button type="primary" @click="queryTable">查询</px-button>
            <px-button @click="resetTable">重置</px-button>
          </px-col>
        </px-row>
      </px-form>
      <div class="equip-table-btn">
        <px-button v-has="'ALL_EQUIP_SPAREPARTS_OUTBOUND_ADD'" style="margin-right: 16px" type="primary" @click="addSpareParts">新增</px-button>
        <px-checkbox v-model="checkedNo" label="按出库单号合并" :disabled="checkedNoDisabled" />
      </div>
      <px-table :data="tableData" class="equip-table" size="small" height="calc(100vh - 346px)" border :span-method="objectSpanMethod">
        <px-table-column label="序号" width="80" align="center" fixed="left">
          <template #default="{ $index }">
            {{ (queryParams.pageNum - 1) * queryParams.pageSize + $index + 1 }}
          </template>
        </px-table-column>
        <px-table-column
          v-for="(item, index) in tableColumns"
          :key="index"
          :label="item.label"
          :min-width="item.minWidth"
          :align="item.align"
          :show-overflow-tooltip="item.showOverflowTooltip"
          :fixed="item.fixed"
        >
          <template #default="scope">
            <px-button v-if="item.outNum && showRowText('ALL_EQUIP_SPAREPARTS_OUTBOUND_VIEW')" link type="primary" @click="handleView(scope.row)">
              {{ scope.row.outNum }}
            </px-button>
            <span v-else-if="item.outNum && !showRowText('ALL_EQUIP_SPAREPARTS_OUTBOUND_VIEW')">{{ scope.row.outNum }}</span>
            <span v-else>{{ scope.row[item.prop] === 0 ? scope.row[item.prop] : scope.row[item.prop] ? scope.row[item.prop] : "-" }}</span>
          </template>
        </px-table-column>
        <px-table-column fixed="right" label="操作" width="180" align="center">
          <template #default="scope">
            <px-tooltip content="详情" placement="top">
              <px-button v-has="'ALL_EQUIP_SPAREPARTS_OUTBOUND_VIEW'" link type="primary" icon="Tickets" @click="handleView(scope.row)" />
            </px-tooltip>
            <px-tooltip content="编辑" placement="top">
              <px-button v-has="'ALL_EQUIP_SPAREPARTS_OUTBOUND_EDIT'" link type="primary" icon="EditPen" @click="handleEdit(scope.row)" />
            </px-tooltip>
            <px-tooltip content="退库" placement="top">
              <px-button v-has="'ALL_EQUIP_SPAREPARTS_OUTBOUND_EXIT'" link type="primary" icon="Logout" @click="handleOut(scope.row)" />
            </px-tooltip>
            <px-tooltip content="删除" placement="top">
              <px-button v-has="'ALL_EQUIP_SPAREPARTS_OUTBOUND_DELETE'" link type="danger" icon="Delete" @click="handleDelete(scope.row)" />
            </px-tooltip>
          </template>
        </px-table-column>
      </px-table>
      <pagination
        v-show="total > 0"
        v-model:page="queryParams.pageNum"
        v-model:limit="queryParams.pageSize"
        class="equip-table-pagination"
        :total="total"
        @pagination="queryTable"
      />
    </div>
    <!-- 详情新增/编辑页面 -->
    <AddSparePartsDetail
      :isMain="isMain"
      :isView="isView"
      :drawerType="drawerType"
      :sparePartsId="sparePartsId"
      :username="username"
      @queryTable="queryTable"
      @backMainPage="backMainPage"
    />
    <!-- 详情查看页面 -->
    <ViewSparePartsDetail
      :isMain="isMain"
      :isView="isView"
      :drawerType="drawerType"
      :sparePartsId="sparePartsId"
      @queryTable="queryTable"
      @backMainPage="backMainPage"
    />
  </div>
</template>

<script setup lang="ts">
defineOptions({
  name: "ALL_EQUIP_SPAREPARTS_OUTBOUND"
});
import { queryDictData } from "@/api/common";
import { getEmployeeIdAndName, showRowText } from "@/utils/pengxi";
import { deleteSparePartsOutbound, querySparePartsOutbound } from "@/api/equip/spareParts";
import { useNav } from "@/layout/hooks/useNav";
import EquipClassSelect from "@/views/all/equip/components/EquipClassSelect.vue";
import { PxMessage, PxMessageBox } from "px-ui";
import { onActivated, onMounted, reactive, toRefs } from "vue";
import { useRoute, useRouter } from "vue-router";
import AddSparePartsDetail from "./components/AddSparePartsDetail.vue";
import ViewSparePartsDetail from "./components/ViewSparePartsDetail.vue";

const route = useRoute();
const router = useRouter();
const { username } = useNav();
const state = reactive<any>({
  isMain: true, // 主页面true 详情页面false
  isView: true, // 查看true 新增/编辑false
  queryParams: {
    outNum: "",
    spareName: "",
    className: "",
    systemCode: "",
    pageNum: 1,
    pageSize: 20
  },
  // 种类、名称、编码、厂区、科室、类型、品牌、厂商型号、厂内型号
  tableColumns: [
    { prop: "outNum", label: "出库单号", minWidth: "220", showOverflowTooltip: true, outNum: true, fixed: "left" },
    { prop: "categoryDesc", label: "种类", minWidth: "100", showOverflowTooltip: true },
    { prop: "recipientName", label: "领用人", minWidth: "130", showOverflowTooltip: true },
    { prop: "sparePartName", label: "名称", minWidth: "130", showOverflowTooltip: true },
    { prop: "sparePartCode", label: "编码", minWidth: "130", showOverflowTooltip: true },
    { prop: "usedDesc", label: "用途", minWidth: "100", showOverflowTooltip: true },
    { prop: "classNameDesc", label: "科室", minWidth: "80", showOverflowTooltip: true },
    { prop: "billNum", label: "关联单据", minWidth: "100", showOverflowTooltip: true },
    { prop: "outDate", label: "出库时间", minWidth: "160", showOverflowTooltip: true },
    { prop: "quantity", label: "出库数量", minWidth: "80", showOverflowTooltip: true },
    { prop: "returnQuantity", label: "退库数量", minWidth: "80", showOverflowTooltip: true }
  ],
  tableData: [],
  total: 0,
  checkedNo: false, // 按出库单号合并
  checkedNoDisabled: true, // 按出库单号合并禁用
  drawerType: "add",
  sparePartsId: "",
  systemCodes: [],
  recipientIdList: [],
  usedList: [],
  categoryList: [],
  isFirstLoad: true
});
const {
  isMain,
  isView,
  queryParams,
  recipientIdList,
  usedList,
  categoryList,
  tableColumns,
  tableData,
  total,
  checkedNo,
  checkedNoDisabled,
  drawerType,
  sparePartsId,
  systemCodes,
  isFirstLoad
} = toRefs(state);

const init = () => {
  const { id, source, code } = route.query;
  if (source && source === "ledger") {
    isMain.value = false;
    isView.value = false;
    drawerType.value = "ledger";
    sparePartsId.value = code;
    return;
  } else if (id) {
    sparePartsId.value = id;
    isMain.value = false;
    isView.value = true;
  } else {
    isMain.value = true;
    isView.value = true;
    queryTable();
  }
  initCategory();
  queryRecipientIdSelect();
  queryUsedSelect();
};
// 进入页面激活时触发
onActivated(() => {
  if (!isFirstLoad.value) {
    init();
  }
});
// 进入页面时触发
onMounted(() => {
  init();
});
// 用途下拉框
const queryUsedSelect = async () => {
  usedList.value = [];
  const params = {
    typeCode: "used"
  };
  const data = await queryDictData(params);
  usedList.value = data;
};
// 领用人人下拉框
const queryRecipientIdSelect = async () => {
  recipientIdList.value = await getEmployeeIdAndName();
};
// 种类下拉框
const initCategory = async () => {
  categoryList.value = [];
  const params = {
    typeCode: "typeCategory"
  };
  const data = await queryDictData(params);
  categoryList.value = data;
};
// 查询备件列表
const queryTable = async () => {
  const params = JSON.parse(JSON.stringify(queryParams.value));
  params.systemCodes = systemCodes.value;
  const data = await querySparePartsOutbound(params);
  tableData.value = data?.data || [];
  total.value = data?.total;
  // 判断按出库单号合并是否禁用
  if (judgeOutNum()) {
    checkedNoDisabled.value = false;
  } else {
    checkedNoDisabled.value = true;
  }
  isFirstLoad.value = false;
};
// 重置筛选条件和备件列表
const resetTable = async () => {
  checkedNo.value = false;
  checkedNoDisabled.value = true;
  queryParams.value = {
    outNum: "",
    spareName: "",
    className: "",
    systemCode: "",
    pageNum: queryParams.value.pageNum,
    pageSize: queryParams.value.pageSize
  };
  systemCodes.value = [];
  queryTable();
};
// 查看备件详情
const handleView = (row: any) => {
  drawerType.value = "view";
  sparePartsId.value = row.id;
  isMain.value = false;
  isView.value = true;
};
// 添加备件详情
const addSpareParts = () => {
  drawerType.value = "add";
  isMain.value = false;
  isView.value = false;
};
// 编辑备件详情
const handleEdit = (row: any) => {
  drawerType.value = "edit";
  sparePartsId.value = row.id;
  isMain.value = false;
  isView.value = false;
};
// 备件退库
const handleOut = (row: any) => {
  drawerType.value = "out";
  sparePartsId.value = row.id;
  isMain.value = false;
  isView.value = true;
};
// 删除备件
const handleDelete = async (row: any) => {
  PxMessageBox.confirm(`要删除当前备件出库单“${row.outNum}”吗？`, "提示", {
    confirmButtonText: "删除",
    confirmButtonClass: "px-button--danger",
    cancelButtonText: "取消",
    type: "warning",
    draggable: true
  })
    .then(async () => {
      const params = {
        id: row.id,
        detailId: row.detailId
      };
      await deleteSparePartsOutbound(params);
      PxMessage.success("删除成功");
      queryTable();
    })
    .catch(() => {});
};
// 从新增/编辑、详情返回主页面
const backMainPage = () => {
  isMain.value = true;
  sparePartsId.value = "";
  // 防止之备件台账跳转详情，返回列表页无数据
  queryTable();
  initCategory();
  queryRecipientIdSelect();
  queryUsedSelect();
  // if (route?.query && route?.query?.source && route?.query?.source === "ledger") {
  //   router.push({ query: {} });
  // } else if (route?.query && route?.query?.id) {
  //   router.push({ query: {} });
  // }
};
// 判断每行的出库单号值都相同
const judgeOutNum = () => {
  if (tableData.value.length > 0) {
    const arr = [];
    tableData.value.forEach(item => {
      arr.push(item.outNum);
    });
    const newArr = Array.from(new Set(arr));
    return arr.length !== newArr.length;
  } else {
    return false;
  }
};
// 表格合并列方法
const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
  if (!checkedNo.value) {
    return [1, 1];
  } else {
    const tableColumn = [{ prop: "index" }, ...tableColumns.value];
    const mergeCols = [
      "outNum",
      "categoryDesc",
      "recipientName",
      "sparePartName",
      "sparePartCode",
      "usedDesc",
      "classNameDesc",
      "billNum",
      "outDate"
    ];
    return getMergeCells(tableData.value, tableColumn, mergeCols)[rowIndex][columnIndex];
  }
};
/**
 * 分析每一列，找出所有【列】可合并（数据相同）的单元格
 * @param {Array} tableData 表数据
 * @param {Array} tableColumn 表字段/表头
 * @param {Array} mergeCols 指定合并哪些列（字段）
 * @returns
 */
const getMergeCells = (tableData = [], tableColumn = [], mergeCols = []) => {
  const fields = tableColumn?.map(v => v.prop);
  const array = [];
  if (!tableData?.length || !tableColumn?.length || !mergeCols?.length) return;
  // 倒叙遍历行（方便统计合并列单元格数至最上方，避免表格塌陷）
  for (let row = tableData.length - 1; row >= 0; row--) {
    array[row] = [];
    for (let col = 0; col < fields.length; col++) {
      // 1.最后一行单元格不合并（初始无可对比数据）
      // 2.不在指定列（mergeCols）的单元格不合并
      // 3.空值不合并
      if (col === 0) {
        array[row][col] = [1, 1];
        continue;
      }
      if (row === tableData.length - 1 || !mergeCols.includes(fields[col]) || !tableData[row][fields[col]]) {
        array[row][col] = [1, 1];
        continue;
      }
      // 4.数据相同但所属父级不一致的单元格不合并
      const parentFields = mergeCols.slice(0, col); // 在指定合并列中找出所有父级
      if (mergeCols.includes(fields[col]) && parentFields?.includes(fields[col - 1])) {
        const currentParents = parentFields.map(field => tableData[row][field]); // 当前单元格所有父级
        const nextRowParents = parentFields.map(field => tableData[row + 1][field]); // 下一行单元格所有父级
        if (currentParents?.toString() !== nextRowParents?.toString()) {
          array[row][col] = [1, 1];
          continue;
        }
      }
      // 5.合并相同数据的单元格
      if (tableData[row][fields[col]] === tableData[row + 1][fields[col]]) {
        const beforeCell = array[row + 1][col];
        array[row][col] = [1 + beforeCell[0], 1];
        beforeCell[0] = 0;
        beforeCell[1] = 0;
      } else {
        array[row][col] = [1, 1]; // 否则不合并
      }
    }
  }
  return array;
};

// 外部封装好的组件
// 科室组件调用父组件
const changeClassName = val => {
  queryParams.value.className = val;
  queryParams.value.systemCode = "";
  systemCodes.value = [];
};
</script>

<style lang="scss" scoped>
@import url("@/views/all/equip/scss/table-list.scss");
</style>
